package cz.muni.fi.pa165.machineryrental.weblayer.controllers;

import cz.muni.fi.pa165.machineryrental.dto.MachineDTO;
import cz.muni.fi.pa165.machineryrental.dto.RevisionDTO;
import cz.muni.fi.pa165.machineryrental.weblayer.utils.Utils;
import cz.muni.fi.pa165.machineryrental.service.MachineService;
import cz.muni.fi.pa165.machineryrental.service.RevisionService;
import cz.muni.fi.pa165.machineryrental.weblayer.editors.MachineEditor;
import cz.muni.fi.pa165.machineryrental.weblayer.validator.RevisionValidator;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

/**
 *
 * @author jostri
 */
@Controller
public class RevisionController {

    @Autowired
    private RevisionService revisionService;
    @Autowired
    private MachineService machineService;

    @InitBinder
    public void initBinder(WebDataBinder webDataBinder) {
        SimpleDateFormat sf = Utils.getCurrentSimpleDateFormat();
        webDataBinder.registerCustomEditor(Date.class, new CustomDateEditor(sf, true));
        webDataBinder.setValidator(new RevisionValidator());
        webDataBinder.registerCustomEditor(MachineDTO.class, new MachineEditor(this.machineService));
    }

    @RequestMapping(value = "/revision/edit/{id}", method = RequestMethod.GET)
    public ModelAndView edit(@PathVariable long id) {

        RevisionDTO revision = this.revisionService.getById(id);
        if (revision == null) {
            return new ModelAndView("/revision/edit.jsp", "revision", null);
        }

        return new ModelAndView("/revision/edit.jsp", "revision", revision);
    }

    @RequestMapping(value = "/revision/edit", method = RequestMethod.POST, params = {"machineId"})
    public ModelAndView edit(@Valid @ModelAttribute("revision") RevisionDTO revision, BindingResult result, @RequestParam("machineId") long machineId) {

        if (result.hasErrors()) {
            return new ModelAndView("/revision/edit.jsp", "revision", revision);
        }

        MachineDTO machine = this.machineService.getById(machineId);
        revision.setMachine(machine);

        this.revisionService.update(revision);
        return new ModelAndView("redirect:/revision/detail/" + revision.getId());
    }

    @RequestMapping("/revision/detail/{id}")
    public ModelAndView detail(@PathVariable long id) {

        RevisionDTO revision = revisionService.getById(id);

        Map<String, Object> model = new HashMap<String, Object>();
        model.put("revision", revision);

        return new ModelAndView("/revision/detail.jsp", "model", model);
    }

    private ModelAndView getModelForAdd(RevisionDTO revision) {
        List<MachineDTO> machines = machineService.findAll();
        Map<String, String> formMachines = new HashMap<String, String>();
        for (MachineDTO m : machines) {
            StringBuilder temp = new StringBuilder(m.getCode());
            temp.append(" - ");
            temp.append(m.getBrand());
            temp.append(" ");
            temp.append(m.getModel());

            formMachines.put(m.getId() + "", temp.toString());
        }

        ModelAndView mav = new ModelAndView("/revision/add.jsp", "revision", revision);
        mav.addObject("machinesMap", formMachines);

        return mav;
    }

    @RequestMapping("/revision/add")
    public ModelAndView add() {

        return this.getModelForAdd(new RevisionDTO());
    }

    @RequestMapping(value = "/revision/add", method = RequestMethod.POST)
    public ModelAndView add(@Valid @ModelAttribute("revision") RevisionDTO revision, BindingResult result) {

        if (result.hasErrors()) {
            return this.getModelForAdd(revision);
        }

//        RevisionDTO revision = new RevisionDTO();
//        MachineDTO machine = machineService.getById(Integer.parseInt(machineId));
//
//        DateFormat formatter = Utils.getCurrentSimpleDateFormat();
//        Date date = formatter.parse(dateOfRevision);
//        revision.setDateOfRevision(date);
//        revision.setMachine(machine);
//        revision.setDescription(description);
        this.revisionService.create(revision);
        return new ModelAndView("redirect:/revision/detail/" + revision.getId());

    }

    @RequestMapping("/revision/remove/{id}")
    public ModelAndView remove(@PathVariable long id) {

        RevisionDTO rental = this.revisionService.getById(id);
        revisionService.remove(rental);
        return new ModelAndView("redirect:/revision/index");
    }
}
